package CutLoad
{
	import CutLoad.cookies.Fun;
	import CutLoad.transitions.ITransition;
	import CutLoad.transitions.SpringMove;
	import CutLoad.transitions.TransitionsData;
	
	
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.Graphics;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.system.ApplicationDomain;

	/**
	 * 基类, 扩展了Sprite的一些方法,注：cutload的可视组件都继承了这个类。它提供了cutload布局时调用的一些接口方法。如果你自定义的元件要加到cutload布局里，请继承这个方法。
	 * @author smallerbird mail:smallerbird@gmail.com  site:www.mkigm.com QQ群:49983196
	 * 
	 */	
	public class Base extends Sprite implements IBase
	{
		/**
		 *保存上一次的坐标x 
		 */		
		protected var LastX:Number=0
		/**
		 *保存上一次的坐标y
		 */	
		protected var LastY:Number=0;
		/**
		 * 其它附加信息
		 */		
		protected var _objOtherInfo:Object=new Object();
		//效果
		protected var transitions_movexy:ITransition;
		/**
		 * 把显示对象转换成Base,其实就是新建一个Base,并包括这个显示对象 
		 * @param displayObj
		 * @return 
		 * 
		 */	
		public static function getBase(displayObj:DisplayObject):Base{
			var baseTem:Base=new Base();
			baseTem.addChild(displayObj);
			return baseTem;
		}
		/**
		 * 从类的字符串里新建一个类 的实例,主要用地皮肤的生成
		 * @param p_name 
		 * @return 
		 * 
		 */		
		public static function getStrClassObject(p_name : String,applicationDomain:ApplicationDomain=null):Object
		{
			try
			{
				if(applicationDomain==null) applicationDomain=ApplicationDomain.currentDomain
				var myclass:Class=applicationDomain.getDefinition(p_name) as Class;
				return new myclass();
			}
			catch (p_e : ReferenceError)
			{
				throw new Error("定义 " + p_name + " 不存在");
				return null;
			}
			return null;
		}
		/**
		 * 从类的字符串里新建一个MovieClip的实例 ,并套一个Base
		 * @param p_name
		 * @return 
		 * 
		 */		
		public static function getStrClassMc(p_name : String):Base{
			return Base.getBase(getMcFromStrClass(p_name));
		}
		/**
		 * 从类的字符串里新建一个MovieClip的实例 
		 * @return 
		 * 
		 */		
		public static function getMcFromStrClass(p_name:String):MovieClip{
			var obj:Object=getStrClassObject(p_name);
			return obj as MovieClip;
		}
		/**
		 * 返回class
		 * @param p_name 
		 * @return 
		 * 
		 */	
		public static function getStrClass(p_name : String):Class
		{
			try
			{
				var myclass:Class=ApplicationDomain.currentDomain.getDefinition(p_name) as Class;
				return myclass;
			}
			catch (p_e : ReferenceError)
			{
				throw new Error("定义 " + p_name + " 不存在");
				return null;
			}
			return null;
		}
		/**
		 * 从库中取得一个MovieClip元件
		 * @param linkName
		 * @return 
		 * 
		 */		
		public static function attachMovie(linkName:String):MovieClip{
			var mc:MovieClip=Base.getStrClassObject(linkName) as MovieClip;
			return mc
		}
		/**
		 * 从库中取得一个BitmapData元件
		 * @param linkName
		 * @return 
		 * 
		 */		
		public static function attachBitmap(linkName:String):BitmapData{
			var mc:BitmapData=Base.getStrClassObject(linkName) as BitmapData;
			return mc
		} 
		/**
		 * 将该对象画在一个BitmapData对象上，并返回。
		 * @return 
		 * 
		 */		
		public function photoMe():BitmapData{
			var img:BitmapData=new BitmapData(this.getShowWidth(),this.getShowHeight(),true,0xffffff);
			img.draw(this);
			return img;
		}
		/**
		 * 消除自已
		 * 
		 */		
		public function killMe():void{
			if(this.parent!=null) this.parent.removeChild(this);
		}
		/**
		 * 对addChilde的扩展，使用这个方法可以方便插入元件同时，设置坐标，同时这个方法返回自已，可以起到连续使用的效果。例如加三个元素： addChildExpand(元素1).addChildExpand(元素2).addChildExpand(元素3)
		 * @param child
		 * @param xx 默认：-10000 表示不设置
		 * @param yy
		 * @return 
		 * 
		 */		
		public function addChildExpand(child:DisplayObject,xx:Number=-10000,yy:Number=-10000):Base{
			this.addChild(child);
			if(xx!=-10000) child.x=xx;
			if(yy!=-10000) child.y=yy;
			return this;
		}
		/**
		 * 设置额外附加信息,注：使用这个方法会清空之前保留的信息，如果要保留之前的一些属性，请使用这个方法：appendOtherInfo
		 * @param obj
		 * 
		 */		
		public function setOtherInfo(obj:Object):void{
			_objOtherInfo=obj;
		}
		/**
		 * 追加额外附加信息的属性
		 * 
		 */		
		public function appendOtherInfo(obj:Object):void{
			Fun.appendObj(obj,_objOtherInfo);
		}
		/**
		 * 获得额外附加信息  与 getOtherInfo()功能相同 
		 * @return 
		 * 
		 */		
		public function get objOtherInfo():Object{
			return _objOtherInfo;
		}
		/**
		 * 获得额外附加信息
		 * @return 
		 * 
		 */		
		public function getOtherInfo():Object{
			return _objOtherInfo;
		}
		/**
		 * 设置位置 
		 * @param x
		 * @param y
		 * @param parent 是否设置要加入的父类，可以为null
		 * @param transitions 过渡效果
		 * 
		 */		
		public function setXY(x:Number,y:Number,myParent:Sprite=null,transitions:ITransition=null):void
		{
			//
			setLastXY(this.x,this.y)
			//
			//移动效果
			//之前的先停下来。
			if(transitions_movexy!=null) transitions_movexy.stop();
			//新的效果结束
			if(transitions!=null){
				var tdata:TransitionsData=new TransitionsData();
				tdata.target=this;
				tdata.x=x;
				tdata.y=y;
				transitions_movexy=transitions.clone(tdata);
				transitions_movexy.start(tdata);
			}else{
				this.x=x;
				this.y=y;
			}
			if(myParent!=null) this.show(myParent);
			
		}
		/**
		 * 设置位置 
		 * @param point
		 * @param myParent
		 * 
		 */		
		public function setXYPoint(point:Point,myParent:Sprite=null):void{
			setXY(point.x,point.y,myParent);
		}
		/**
		 * 以我为坐标的几个相对位置 
		 * @param t  0居中,1左上,2上中,3右上,4右中,5右下,6下中,7左下,8左中
		 * @param base 如果不为空，将会设置它的位置。
		 * @return 
		 * 
		 */		
		public function followMe(t:Number,base:Base=null):Point{
			var atPoint:Point;
			switch(t){
				case 1:
					atPoint=new Point(x,y);
					break;
				case 2:
					atPoint=this.getXYUpCenter();
					break;
				case 3:
					atPoint=this.getXYRightUp();
					break;
				case 4:
					atPoint=this.getXYRightCenter();
					break;
				case 5:
					atPoint=this.getXYRightDown();
					break;
				case 6:
					atPoint=this.getXYDownCenter()
					break;
				case 7:
					atPoint=this.getXYLeftDown();
					break;
				case 8:
					atPoint=this.getXYLeftCenter();
					break;
				default:
					atPoint=this.getXYCenter();
					break;
			}
			if(base!=null) base.setXYPoint(atPoint);
			return atPoint;
		}
		/**
		 * 比较前一次设置位置的坐标是否相同 
		 * @param xx
		 * @param yy
		 * @return 
		 * 
		 */		
		public function compareLastXY(xx:Number,yy:Number):Boolean{
			if(xx==this.LastX&&yy==this.LastY) return true;
			return false;
		}
		/**
		 * 设置回上一次设置的坐标 
		 * 
		 */		
		public function resetLastXY():void{
			this.setXY(this.LastX,this.LastY);
		}
		/**
		 * 设置lastX lastY 
		 * @param xx
		 * @param yy
		 * 
		 */		
		public function setLastXY(xx:Number,yy:Number):void{
			this.LastX=xx;
			this.LastY=yy;
		}
		/**
		 * 设置宽高
		 * @param w 宽
		 * @param h 高
		 * 
		 */		
		public function setWH(w:Number=0,h:Number=0):void{
			if(w!=0) this.width=w;
			if(h!=0) this.height=h;
		}
		/**
		 * 设置宽高,宽度高度的值从继承IBase接口的getShowWidth() 和 getShowHeight() 里获得。
		 * @param base
		 * 
		 */		
		public function setWHFormBase(base:IBase):void{
			setWH(base.getShowWidth(),base.getShowHeight())
		}
		/**
		 * 设置部份子元件的透明值 
		 * @param a
		 * 
		 */		
		public function setAlpha(a:Number):void{
			this.alpha=a;
		}
		/**
		 * 在该类中，添加该元素 
		 * @param parent 父类显示对象
		 * 
		 */		
		public function show(parent:Sprite):void{
			if(this.parent!=null){
				trace("警告:Base.show()自已的parent!=null!!");
				return;
			}
			parent.addChild(this);
		}
		/**
		 * 获得显示的宽度 
		 * @return 
		 * 
		 */		
		public function getShowWidth():Number
		{
			return this.width;
		}
		/**
		 * 获得显示的高度  
		 * @return 
		 * 
		 */		
		public function getShowHeight():Number
		{
			return this.height;
		}
		/**
		 * 获得右上角的坐标
		 * @return
		 * 
		 */		
		public function getXYRightUp():Point{
			return new Point(x+getShowWidth(),y);
		}
		/**
		 * 获得右下角的坐标
		 * @return 格式:{x:xx,y:yy}
		 * 
		 */		
		public function getXYRightDown():Point{
			return new Point(x+getShowWidth(),y+getShowHeight());
		}
		/**
		 * 获得左下角的坐标 
		 * @return 格式:{x:xx,y:yy}
		 * 
		 */
		public function getXYLeftDown():Point{
			return new Point(x,y+getShowHeight());
		}
		/**
		 * 获得上中点 
		 * @return 
		 * 
		 */		
		public function getXYUpCenter():Point{
			return new Point(x+getShowWidth()/2,y);
		}
		/**
		 * 获得右中点 
		 * @return 
		 * 
		 */		
		public function getXYRightCenter():Point{
			return new Point(x+getShowWidth(),y+this.getShowHeight()/2);
		}
		/**
		 * 获得上中点 
		 * @return 
		 * 
		 */		
		public function getXYDownCenter():Point{
			return new Point(x+getShowWidth()/2,y+this.getShowHeight());
		}
		/**
		 * 获得左中点 
		 * @return 
		 * 
		 */		
		public function getXYLeftCenter():Point{
			return new Point(x,y+this.getShowHeight()/2);
		}
		/**
		 * 获得中心点 
		 * @return 
		 * 
		 */		
		public function getXYCenter():Point{
			return new Point(x+getShowWidth()/2,y+this.getShowHeight()/2);
		}
		/**
		 * 用point对象设置显示对象位置 
		 * @param point
		 * @param myParent
		 * 
		 */		
		public function setPosition(point:Point,myParent:Sprite=null):void{
			this.setXY(point.x,point.y,myParent);
		}
		/**
		 * 返回位置Point对象
		 * @return 
		 * 
		 */		
		public function getPosition():Point{
			return new Point(x,y);
		}
		/**
		 * 返回对象的 Rectangle信息
		 * @return 
		 * 
		 */		
		public function getRectInfo():Rectangle{
			return new Rectangle(x,y,this.getShowWidth(),this.getShowHeight())	;
		}
		/**
		 * 打印信息 
		 * 
		 */		
		public function printInfon():void{
			
		}
	}
}